/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain one copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mikepenz.iconics.sample.provider;

import ohos.agp.components.AttrHelper;
import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ListContainer;
import ohos.agp.components.StackLayout;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
import ohos.app.Context;

import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.sample.ResourceTable;
import com.mikepenz.iconics.sample.item.IconItem;
import com.mikepenz.iconics.typeface.ITypeface;
import com.mikepenz.iconics.view.IconicsImageView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 主页面图标迭代器
 *
 * @since 2021-06-16
 */
public class IconItemProvider extends BaseItemProvider {
    private final List<IconItem> icons = new ArrayList<>();
    private final Context context;
    private final Random random = new Random();
    private boolean randomize = false;
    private boolean shadow = false;
    private final List<IconItem> cache = new ArrayList<>();
    private final ListContainer listContainer;
    private OnItemClickedListener onItemClickedListener;

    /**
     * 构造方法
     *
     * @param context 上下文
     * @param listContainer 组件
     */
    public IconItemProvider(Context context, ListContainer listContainer) {
        this.context = context;
        this.listContainer = listContainer;
    }

    /**
     * 设置随机数
     *
     * @param randomize 随机数
     */
    public void setRandomize(boolean randomize) {
        this.randomize = randomize;
        notifyDataChanged();
    }

    /**
     * 设置阴影变化
     *
     * @param shadow 阴影
     */
    public void setShadow(boolean shadow) {
        this.shadow = shadow;
        notifyDataChanged();
    }

    /**
     * 设置字体界限
     */
    public void respectFontBounds() {
        notifyDataChanged();
    }

    /**
     * 刷新数据源
     *
     * @param typeface 字体
     */
    public void refreshData(ITypeface typeface) {
        icons.clear();
        if (typeface != null) {
            List<String> list = typeface.getIcons();
            for (String icon : list) {
                IconItem iconItem = new IconItem(icon);
                icons.add(iconItem);
            }
        }
        cache.clear();
        cache.addAll(icons);
        notifyDataChanged();
        listContainer.scrollTo(0, 0);
    }

    /**
     * 按传入字符搜索
     *
     * @param keyword 关键字
     */
    public void onSearch(String keyword) {
        if (keyword == null) {
            icons.clear();
            icons.addAll(cache);
        } else {
            List<IconItem> searchResult = new ArrayList<>();
            for (IconItem icon : cache) {
                if (icon.getIcon().contains(keyword)) {
                    searchResult.add(icon);
                }
            }
            icons.clear();
            icons.addAll(searchResult);
        }
        notifyDataChanged();
    }

    @Override
    public int getCount() {
        return icons.size() % 2 == 0 ? icons.size() / 2 : icons.size() / 2 + 1;
    }

    @Override
    public Object getItem(int position) {
        if (position > icons.size() - 1) {
            return null;
        }
        return icons.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * 条目点击监听接口
     *
     * @since 2021-06-16
     */
    public interface OnItemClickedListener {
        /**
         * 点击监听
         *
         * @param position 索引
         * @param component 组件
         */
        void onItemClicked(int position, Component component);
    }

    public void setOnItemClickedListener(OnItemClickedListener listener) {
        onItemClickedListener = listener;
    }

    @Override
    public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
        ItemHolder itemHolder;
        if (convertComponent == null) {
            itemHolder = new ItemHolder();
            convertComponent = LayoutScatter.getInstance(context)
                .parse(ResourceTable.Layout_row_icon, null, false);
            itemHolder.icon1 = (IconicsImageView) convertComponent.findComponentById(ResourceTable.Id_icon1);
            itemHolder.name1 = (Text) convertComponent.findComponentById(ResourceTable.Id_name1);
            itemHolder.itemContainer1 = (StackLayout) convertComponent.findComponentById(ResourceTable.Id_item1);
            itemHolder.icon2 = (IconicsImageView) convertComponent.findComponentById(ResourceTable.Id_icon2);
            itemHolder.name2 = (Text) convertComponent.findComponentById(ResourceTable.Id_name2);
            itemHolder.itemContainer2 = (StackLayout) convertComponent.findComponentById(ResourceTable.Id_item2);
            convertComponent.setTag(itemHolder);
        } else {
            itemHolder = (ItemHolder) convertComponent.getTag();
        }
        if (position == getCount() - 1) {
            convertComponent.setMarginBottom(AttrHelper.vp2px(8, context));
        } else {
            convertComponent.setMarginBottom(0);
        }
        IconItem item = (IconItem) getItem(position * 2);
        IconItem item2 = (IconItem) getItem(position * 2 + 1);
        itemHolder.itemContainer1.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (onItemClickedListener != null) {
                    onItemClickedListener.onItemClicked(position * 2, component);
                }
            }
        });
        itemHolder.itemContainer2.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (onItemClickedListener != null) {
                    onItemClickedListener.onItemClicked(position * 2 + 1, component);
                }
            }
        });
        bindData(item, item2, itemHolder, position);
        return convertComponent;
    }

    private void bindData(IconItem item1, IconItem item2, ItemHolder itemHolder, int position) {
        bindItem1(item1, itemHolder, position);
        bindItem2(item2, itemHolder, position);
    }

    private void bindItem1(IconItem item1, ItemHolder itemHolder, int position) {
        if (item1 != null) {
            String icon = item1.getIcon();
            IconicsDrawable drawable = new IconicsDrawable(itemHolder.icon1, context, icon);
            drawable.setRespectFontBounds(true);
            if (randomize) {
                drawable.setColor(getRandomColor(position));
                drawable.setPaddingPx(AttrHelper.vp2px(random.nextInt(12), context));
                drawable.setContourWidthPx(AttrHelper.vp2px(random.nextInt(2), context));
                drawable.setContourColor(getRandomColor(position - 2));
                int y = random.nextInt(10);
                if (y % 4 == 0) {
                    drawable.setBackgroundColor(getRandomColor(position - 4));
                    drawable.setRoundCornerSize(AttrHelper.vp2px(2 + random.nextInt(10), context));
                }
            }
            if (shadow) {
                int offset = AttrHelper.vp2px(1, context);
                drawable.setShadowRadiusPx(offset);
                drawable.setShadowDxPx(offset);
                drawable.setShadowDyPx(offset);
                drawable.setShadowColorInt(new Color(0xcc000000));
            }
            itemHolder.icon1.setIcon(drawable);
            itemHolder.name1.setText(icon);
        }
    }

    private void bindItem2(IconItem item2, ItemHolder itemHolder, int position) {
        if (item2 != null) {
            itemHolder.itemContainer2.setVisibility(Component.VISIBLE);
            String icon = item2.getIcon();
            IconicsDrawable drawable = new IconicsDrawable(itemHolder.icon2, context, icon);
            drawable.setRespectFontBounds(true);
            if (randomize) {
                drawable.setColor(getRandomColor(position));
                drawable.setPaddingPx(random.nextInt(12));
                drawable.setContourWidthPx(random.nextInt(2));
                drawable.setContourColor(getRandomColor(position - 2));
                int y = random.nextInt(10);
                if (y % 4 == 0) {
                    drawable.setBackgroundColor(getRandomColor(position - 4));
                    drawable.setRoundCornerSize(AttrHelper.vp2px(2 + random.nextInt(10), context));
                }
            }
            if (shadow) {
                int offset = AttrHelper.vp2px(1, context);
                drawable.setShadowRadiusPx(offset);
                drawable.setShadowDxPx(offset);
                drawable.setShadowDyPx(offset);
                drawable.setShadowColorInt(new Color(0xcc000000));
            }
            itemHolder.icon2.setIcon(drawable);
            itemHolder.name2.setText(icon);
        } else {
            itemHolder.itemContainer2.setVisibility(Component.INVISIBLE);
        }
    }

    private Color getRandomColor(int position) {
        int index = Math.abs(position) % 10;
        switch (index) {
            case 1:
                return new Color(0xff2196f3);
            case 2:
                return new Color(0xff4caf50);
            case 3:
                return new Color(0xfff44336);
            case 4:
            case 8:
                return new Color(0xffff9800);
            case 5:
                return new Color(0xffe91e63);
            case 6:
                return new Color(0xffffc107);
            case 7:
                return new Color(0xff607d8b);
            case 9:
                return new Color(0xffffeb3b);
            default:
                return new Color(0xff000000);
        }
    }

    /**
     * 布局对象持有者，复用机制
     *
     * @since 2021-06-16
     */
    private static class ItemHolder {
        private StackLayout itemContainer1;
        private StackLayout itemContainer2;
        private IconicsImageView icon2;
        private IconicsImageView icon1;
        private Text name1;
        private Text name2;
    }
}
